home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir34 / xpcbpath.zip / XPCBPATH.C < prev    next >
C/C++ Source or Header  |  1994-06-04  |  8KB  |  405 lines

  1. /* -----------------------------------------------------------------------
  2.     XPCBPATH Version 1.0, June 4, 1994.
  3.     (c) 1994 Key Software Products.
  4.     All Rights Reserved.
  5.  
  6.     This software is copyrighted.  You are free to use it as you
  7.     like, except:
  8.  
  9.     (1) If modified, you must keep the copyright notice in the
  10.         source and executable code, and this comment in the source.
  11.  
  12.     (2) It may not be incorporated into a commercial product without
  13.         the author's permission.
  14.  
  15.    -----------------------------------------------------------------------
  16.    This software has been compiled with the DeSmet C88 compiler and linker.
  17.    ----------------------------------------------------------------------- */
  18.  
  19. #include    <stdio.h>
  20.  
  21. #define    PGM_NAME    "XPCBPATH"
  22. #define    VERSION        "1.0"
  23.  
  24. #define    MAX_ENTRIES    100
  25.  
  26. #define    STACK_SIZE    512
  27.  
  28. #define    PCBSIZE        31
  29. #define    DOSSIZE        65
  30.  
  31. #define    ENDOF(bfr)    &bfr[strlen(bfr)]
  32.  
  33. typedef struct PATH
  34.     {
  35.     char    old[PCBSIZE] ;
  36.     char    new[DOSSIZE] ;
  37.     } PATH ;
  38.  
  39. char path[DOSSIZE] ;
  40. char rest[DOSSIZE] ;
  41.  
  42. unsigned entries = 0 ;
  43. PATH subst[MAX_ENTRIES] ;
  44.  
  45. /* These functions must be in the resident portion of the code segment */
  46. /* If we use the ones in the library, they'll be tacked on to the end  */
  47. /* of this code, and then discarded when we go TSR!               */
  48.  
  49. #define    strlen        _strlen
  50. #define    strcpy        _strcpy
  51. #define strncat        _strncat
  52. #define toupper        _toupper
  53. #define    strncmpi    _strncmpi
  54.  
  55. void Sign_On(void) ;
  56. unsigned showcs(void) ;
  57. unsigned showds(void) ;
  58. void lmove(unsigned, unsigned, unsigned, unsigned, unsigned) ;
  59. int strlen(char *) ;
  60. void strcpy(char *, char *) ;
  61. void strncat(char *, char *, int) ;
  62. char toupper(char) ;
  63. int strncmpi(char *, char *, int) ;
  64. char *Fix_Path(char *, unsigned) ;
  65. void TSR(unsigned, unsigned) ;
  66. void CS_End(void) ;
  67. unsigned Substitute(int, char *[]) ;
  68. void Announce(unsigned, char *, char *) ;
  69. void Usage(char *) ;
  70.  
  71. void Int21()
  72.     {
  73. #ifndef    _lint
  74. #asm
  75. ;----------------------------------------------------------
  76. New_Int21:
  77. ;----------------------------------------------------------
  78.         pushf            ; Preserve flags
  79.         cmp    ah,3Bh        ; Set current directory?
  80.         je    Subst
  81.         cmp    ah,3Dh        ; Open file?
  82.         je    Subst
  83.         cmp    ax,4300h    ; Get file attributes?
  84.         je    Subst
  85.         cmp    ah,4Eh        ; Find first?
  86.         je    Subst
  87.         popf            ; Restore flags
  88.  
  89.         db    0EAh        ; JMP FAR DIRECT
  90. Old_Int21    dw    0        ;  offset
  91.         dw    0        ;  segment
  92.  
  93. save_ss        dw    0
  94. save_sp        dw    0
  95.  
  96. stack_seg    dw    0
  97. stack_ptr    dw    0
  98.  
  99. Subst:        add    sp,2        ; Discard flags saved above
  100.  
  101.     ; Important input registers: AX, CX, DS:DX
  102.  
  103.         mov    save_ss,ss    ; preserve stack
  104.         mov    save_sp,sp
  105.  
  106.         mov    ss,stack_seg    ; establish my stack
  107.         mov    sp,stack_ptr
  108.  
  109.         push    bx        ; preserve irrelevant registers
  110.         push    si
  111.         push    di
  112.         push    es
  113.  
  114.         push    ax        ; preserve relevant registers
  115.         push    cx
  116.         push    ds        ; parameter #2 (segment)
  117.         push    dx        ; parameter #1 (offset)
  118.  
  119.         mov    ds,stack_seg    ; establish my data segment
  120.         call    Fix_Path_    ; returns DS:AX => new path
  121.         mov    dx,ax
  122.  
  123.         pop    di        ; save original DX in DI
  124.         pop    si        ; save original DS in SI
  125.         pop    cx        ; restore other relevant registers
  126.         pop    ax
  127.  
  128.         pushf            ; Simulate INT 21h
  129.         lcall    DWORD Old_Int21    ; Don't change CF or AX after here!
  130.  
  131.         mov    dx,di        ; restore REAL DX
  132.         mov    ds,si        ; restore REAL DS
  133.  
  134.         pop    es        ; restore irrelevant registers
  135.         pop    di
  136.         pop    si
  137.         pop    bx
  138.  
  139.         mov    ss,save_ss
  140.         mov    sp,save_sp
  141.  
  142.         lret    2
  143. #end
  144. #endif
  145.     }
  146.  
  147. unsigned showds()
  148.     {
  149. #ifndef    _lint
  150. #asm
  151.         mov    ax,ds
  152. #end
  153. #endif
  154.     }
  155.  
  156. unsigned showcs()
  157.     {
  158. #ifndef    _lint
  159. #asm
  160.         mov    ax,cs
  161. #end
  162. #endif
  163.     }
  164.  
  165. void lmove(bytes, src_off, src_seg, dst_off, dst_seg)
  166. unsigned bytes ;
  167. unsigned src_off ;
  168. unsigned src_seg ;
  169. unsigned dst_off ;
  170. unsigned dst_seg ;
  171.     {
  172. #ifndef    _lint
  173. #asm
  174.         push    ds
  175.         mov    cx,#bytes
  176.         les    di,#dst_off
  177.         lds    si,#src_off
  178.         cld
  179.         rep    movsb
  180.         pop    ds
  181. #end
  182. #endif
  183.     }
  184.  
  185. char *Fix_Path(off, seg)
  186. char *off ;
  187. unsigned seg ;
  188.     {
  189.     int i, len ;
  190.     PATH *p ;
  191.  
  192.     lmove(sizeof(path), off, seg, path, showds()) ;
  193.     p = subst ;
  194.     for (i = 0; i < entries; i++, p++)
  195.         {
  196.         len = strlen(p->old) ;
  197.         if (strncmpi(path, p->old, len) == 0)
  198.             {
  199.             strcpy(rest, path + len) ;
  200.             strcpy(path, p->new) ;
  201.             strncat(path, rest, (DOSSIZE - 1) - strlen(p->new)) ;
  202.             break ;
  203.             }
  204.         }
  205.  
  206.     return path ;
  207.     }
  208.  
  209. int strlen(str)
  210. char *str ;
  211.     {
  212.     int len ;
  213.  
  214.     len = 0 ;
  215.     while (*str++) len++ ;
  216.     return len ;
  217.     }
  218.  
  219. void strcpy(dst, src)
  220. char *dst ;
  221. char *src ;
  222.     {
  223.     while (*src) *dst++ = *src++ ;
  224.     *dst = '\0' ;
  225.     }
  226.  
  227. void strncat(dst, src, n)
  228. char *dst ;
  229. char *src ;
  230. int n ;
  231.     {
  232.     dst += strlen(dst) ;
  233.     while (*src && n--) *dst++ = *src++ ;
  234.     *dst = '\0' ;
  235.     }
  236.  
  237. char toupper(ch)
  238. char ch ;
  239.     {
  240.     if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 'A' ;
  241.     return ch ;
  242.     }
  243.  
  244. int strncmpi(str1, str2, n)
  245. char *str1 ;
  246. char *str2 ;
  247. int n ;
  248.     {
  249.     char ch1, ch2 ;
  250.  
  251.     while (*str1 && *str2 && n--)
  252.         {
  253.         ch1 = toupper(*str1++) ;
  254.         ch2 = toupper(*str2++) ;
  255.         if (ch1 != ch2) return 1 ;
  256.         }
  257.     return 0 ;
  258.     }
  259.  
  260. void TSR(stk_ptr, stk_seg)
  261. unsigned stk_ptr ;
  262. unsigned stk_seg ;
  263.     {
  264. #ifndef    _lint
  265. #asm
  266.         mov    ax,#stk_ptr
  267.         mov    WORD stack_ptr,ax
  268.         mov    ax,#stk_seg
  269.         mov    stack_seg,ax
  270.  
  271.         xor    ax,ax
  272.         mov    ds,ax
  273.  
  274.     ; preserve old int 21h vector
  275.  
  276.         les    ax,[4*21h]
  277.         mov    Old_Int21[0],ax
  278.         mov    Old_Int21[2],es
  279.  
  280.     ; modify int 21h vector
  281.  
  282.         cli
  283.         mov    WORD [4*21h+0],OFFSET New_Int21
  284.         mov    WORD [4*21h+2],cs
  285.         sti
  286.  
  287.     ; terminate but stay resident
  288.  
  289.         mov    dx,stack_seg
  290.         mov    ax,cs
  291.         sub    dx,ax            ; DX = para size of cseg
  292.         mov    ax,stack_ptr
  293.         add    ax,256+15        ; PSP plus rounding
  294.         mov    cl,4
  295.         shr    ax,cl            ; AX = stack paragraphs
  296.         add    dx,ax
  297.         mov    ax,3100h
  298.         int    21h
  299. #end
  300. #endif
  301.     }
  302.  
  303. void main(argc, argv)
  304. int argc ;
  305. char *argv[] ;
  306.     {
  307.     unsigned size, dseg ;
  308.  
  309.     Sign_On() ;
  310.     entries = Substitute(argc, argv) ;
  311.     dseg = showcs() + (((unsigned) CS_End + 15) >> 4) ;
  312.     size = subst + entries ;
  313.     lmove(size, 0, showds(), 0, dseg) ;
  314.     TSR(size + STACK_SIZE, dseg) ;
  315.     }
  316.  
  317. void CS_End()    /* Only initialization code below here! */
  318.     {
  319.     }
  320.  
  321. unsigned Substitute(argc, argv)
  322. int argc ;
  323. char *argv[] ;
  324.     {
  325.     unsigned entries = 0 ;
  326.     char *p, bfr[100] ;
  327.     FILE *fp ;
  328.  
  329.     if (argc != 2) Usage("Wrong number of command line arguments") ;
  330.  
  331.     fp = fopen(argv[1], "r") ;
  332.     if (!fp) Usage("Can't find file") ;
  333.  
  334.     puts("") ;
  335.     while (fgets(bfr, sizeof(bfr), fp))
  336.         {
  337.         if (p = strchr(bfr, '\n')) *p = '\0' ;
  338.         while (isspace(*bfr)) strcpy(bfr, bfr + 1) ;
  339.         if (p = strpbrk(bfr, " \t"))
  340.             {
  341.             char *old, *new ;
  342.  
  343.             old = bfr ;
  344.             *p++ = '\0' ;
  345.             while (isspace(*p)) p++ ;
  346.             new = p ;
  347.             if (p = strpbrk(new, " \t")) *p = '\0' ;
  348.             strncpy(subst[entries].old, old, PCBSIZE - 1) ;
  349.             strncpy(subst[entries].new, new, DOSSIZE - 1) ;
  350.             entries++ ;
  351.             Announce(entries, old, new) ;
  352.             if (entries >= MAX_ENTRIES) break ;
  353.             }
  354.         }
  355.  
  356.     fclose(fp) ;
  357.  
  358.     return entries ;
  359.     }
  360.  
  361. void Announce(entry, old, new)
  362. unsigned entry ;
  363. char *old ;
  364. char *new ;
  365.     {
  366.     char bfr[100] ;
  367.  
  368.     strcpy(bfr, "\t") ;
  369.     ltoa((long) entry, ENDOF(bfr), 10) ;
  370.     strcat(bfr, ": ") ;
  371.     strcat(bfr, old) ;
  372.     strcat(bfr, " ==> ") ;
  373.     strcat(bfr, new) ;
  374.     puts(bfr) ;
  375.     }
  376.  
  377. void Sign_On()
  378.     {
  379.     char bfr[100] ;
  380.  
  381.     strcpy(bfr, "\n") ;
  382.     strcat(bfr, PGM_NAME) ;
  383.     strcat(bfr, " v") ;
  384.     strcat(bfr, VERSION) ;
  385.     strcat(bfr, " (c) 1994 Key Software Products.  All Rights Reserved.");
  386.     puts(bfr) ;
  387.     }
  388.  
  389. void Usage(msg)
  390. char *msg ;
  391.     {
  392.     char bfr[100] ;
  393.  
  394.     strcpy(bfr, "\n\tError: ") ;
  395.     strcat(bfr, msg) ;
  396.     puts(bfr) ;
  397.  
  398.     strcpy(bfr, "\n\tUsage: ") ;
  399.     strcat(bfr, PGM_NAME) ;
  400.     strcat(bfr, " <filespec>") ;
  401.     puts(bfr) ;
  402.  
  403.     exit(255) ;
  404.     }
  405.